from flask import  Blueprint,views,render_template,request,session,g,url_for,jsonify,abort
from .forms import SignUpForm,SigninForm,ADDPostForm,ADDCommentForm
from utils import  resful,safeutils
from .models import FrontUser
from exts import db
from .describes import login_request
from apps.models import BoardModels,BannerModels,PostModels,CommentsModels,HighlightPostModels
import config
from flask_paginate import Pagination,get_page_parameter
from sqlalchemy.sql import func

bp = Blueprint("front", __name__)

@bp.route("/")
def index():
    page = request.args.get(get_page_parameter(), type=int, default=1)
    board_id = request.args.get("bd",type=int,default=None)
    sort_id = request.args.get("st",type=int,default=1)
    banners = BannerModels.query.order_by(BannerModels.priority.desc()).limit(4)
    boards = BoardModels.query.all()
    start = (page-1) * config.PER_PAGE
    end = start + config.PER_PAGE
    posts = None
    total = None
    query_obj = None
    if sort_id == 1:
        query_obj = PostModels.query.order_by(PostModels.create_time.desc())
    elif sort_id == 2:
        query_obj = db.session.query(PostModels).outerjoin(HighlightPostModels).order_by(HighlightPostModels.create_time.desc(),PostModels.create_time.desc())
    elif sort_id == 3:
        query_obj = PostModels.query.order_by(PostModels.create_time.desc())
    elif sort_id == 4:
        query_obj = db.session.query(PostModels).outerjoin(CommentsModels).group_by(PostModels.id).order_by(func.count(CommentsModels.id).desc(),PostModels.create_time.desc())
    if not board_id:
        posts = query_obj.slice(start,end)
        total = PostModels.query.order_by(PostModels.create_time.desc()).count()
    else:
        query_obj = query_obj.filter(PostModels.board_id == board_id)
        posts = query_obj.slice(start,end)
        total = PostModels.query.filter(PostModels.board_id == board_id).order_by(PostModels.create_time.desc()).count()
    paginantion = Pagination(bs_version=3,page=page,total=total,outer_window=0)
    context = {
        "boards":boards,
        "banners": banners,
        "posts": posts,
        "paginantion": paginantion,
        "current_board": board_id,
        "current_sort" : sort_id

    }
    return render_template("front/front_index.html",**context)


@bp.route("/apost/",methods=["GET","POST"])
@login_request
def apost():
    board = BoardModels.query.all()
    context = {
        "boards": board
    }
    if request.method == "GET":
        return render_template("front/front_posts.html", **context)
    elif request.method == "POST":
        form = ADDPostForm(request.form)
        if form.validate():
            title = form.title.data
            context = form.context.data
            board_id = form.board_id.data
            author = g.front_user
            # print(title,board_id)
            board = BoardModels.query.get(board_id)
            if not board:
                return  resful.paraserror(message="板块不存在")
            else:
                post = PostModels(title=title,context=context,author=author)
                post.board = board
                db.session.add(post)
                db.session.commit()
                db.session.commit()
                return resful.success()
        else:
            return resful.paraserror(form.get_errors())


@bp.route("/p/<post_id>")
def post_detail(post_id):
    post = PostModels.query.get(post_id)
    if not post:
        abort(404)
    else:
        return render_template("front/front_post_detail.html",post=post)



@bp.route("/editor/")
def editor():
    return  render_template("front/front_editor.html")

@bp.route("/ueditor/")
def ueditor():
    return  render_template("front/front_ueditor.html")



class SignupView(views.MethodView):
    def get(self):
        #request.referrer 返回上一个浏览过的页面
        return_to = request.referrer

        #request.url 获取请求时当前页面的url
        if return_to and return_to != request.url and safeutils.is_safe_url(return_to):
            return render_template("front/front_signup.html",return_to=return_to)
        else:
            return  render_template("front/front_signup.html")
    def post(self):
        form = SignUpForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            username = form.username.data
            password = form.password1.data


            user = FrontUser(telephone=telephone,username=username,password=password)
            db.session.add(user)
            db.session.commit()
            return resful.success()
        else:
            # print(form.get_errors())
            return resful.paraserror(message=form.get_errors())

@bp.route("/addcomment/",methods=["GET","POST"])
@login_request
def addcomment():
    if request.method == "GET":
        pass
    if request.method == "POST":
        form = ADDCommentForm(request.form)
        if form.validate():
            post_id = form.post_id.data
            context = form.context.data
            post = PostModels.query.get(post_id)
            if not post:
                return resful.paraserror(message="没有这篇帖子")
            author = g.front_user
            comment = CommentsModels(post=post,context=context)
            comment.author = author
            db.session.add(comment)
            db.session.commit()
            return resful.success()
        else:
            return  resful.paraserror(message=form.get_errors())





class SigninView(views.MethodView):
    def get(self):
        return_to = request.referrer
        if return_to and return_to != url_for("front.signup") and safeutils.is_safe_url(return_to) and return_to != request.url:
            return render_template("front/front_signin.html",return_to=return_to)
        else:
            return render_template("front/front_signin.html")

    def post(self):
        form = SigninForm(request.form)
        if form.validate():
            telephone = form.telephone.data
            password = form.password.data
            remember = form.remember.data
            print(telephone,password,remember)
            user = FrontUser.query.filter(FrontUser.telephone == telephone).first()
            if user and user.check_password(password):
                session[config.FRONT_USER_ID] = user.id
                if remember:
                    print("remember me")
                    session.permanent = True
                    print(session.permanent)
                return resful.success()
            else:
                return  resful.paraserror(message="手机号码或者密码错误")
        else:
            return resful.paraserror(message=form.get_errors())


bp.add_url_rule("/signup/",view_func=SignupView.as_view("signup"))
bp.add_url_rule("/signin/",view_func=SigninView.as_view("signin"))